home *** CD-ROM | disk | FTP | other *** search
- ; Millisecond timer mini-driver
- ; Written by Scott Gillespie
- ; in the Reed College MacLab V85.01.14
- ;
- ; Modified on 6-Oct-1986 by
- ; David Powell, Research Services Branch, NIH
- ; Building 36, Room 2A03
- ; Bethesda, MD 20892
- ;
- ; Converted .PROC and .LONG to XDEF and DC.L for MDS
- ; Bug Fix: Reversed order of Unlk and Movem in Exit.
- ;
- ; This code contains a miniature driver for doing millisecond
- ; timing on the Macintosh. The 6522 (VIA) chip's Timer1 is
- ; loaded with a value that causes an interrupt every millisecond.
- ; A LongInt variable is incremented after each interrupt. The
- ; variable can then be read to determine how many milliseconds
- ; passed since the timer was started.
- ;
- ; Note 1: VIA's Timer1 is also used by the sound driver, so any
- ; use of the sound driver will temporarily stop the counter.
- ;
- ; Note 2: Be sure to turn off the timer when you are through
- ; with it.
- ;
- ; The mini-driver consists of four routines:
- ;
- ; InitTimer -- Set up timer; call once at beginning of your program
- ; KillTimer -- Turn off timer and restore Sound driver handler
- ; ResetTimer -- Set counter to zero
- ; count:=TimerValue -- Get current millisecond count
- ;
- ; VIA input = systemclock / 10 = 783,360 cycles/sec
- ; VIA Timer1 value for 1 ms = 782 (783-1) = 3 * 256 + 14
- ;
- ; To understand all this, it helps to have the 6522 manual
- ; which describes Timer1 operation, plus IM V3 Ch 2 (Mac
- ; Hardware) and IM V2 Ch 6 (Device Manager). See especially
- ; pp III-39 to III-45 on the VIA and II-195 to II-200 on
- ; interrupt handlers.
- ;
- .Listtofile timer.Lst
-
- LowCount equ 14 ; low byte, Timer1
- HighCount equ 3 ; high byte, Timer1
-
- Lvl1DT equ $192 ; From SYSEQU.TXT
- VIA equ $1d4
- vT1C equ $800
- vT1CH equ $A00
- vT1L equ $C00
- vACR equ $1600
- vIER equ $1C00
-
- xdef InitTimer,ResetTimer,TimerValue,KillTimer
-
- InitTimer
- movem.l a0-a1,-(sp) ; Save registers
- movea.l #Lvl1dt,a0 ; Save Level 1 dispatch table
- lea LastVIA,a1 ; interrupt handler for later
- move.l 24(a0),(a1)
- lea VIArout,a1 ; Install my interrupt handler
- move.l a1,24(a0) ; in dispatch table
- movea.l VIA,a1 ; Get VIA address and set up Timer1
- ori.b #$40,VACR(a1) ; in free-run mode
- move.b #$c0,VIER(a1) ; Enable VIA interrupts ($80+$40)
- move.b #LowCount,VT1l(a1) ; Load low latch
- move.b #HighCount,VT1CH(a1) ; Load high counter/latch
- lea counter,a0 ; Get counter address
- clr.l (a0) ; Zero counter
- movem.l (sp)+,a0-a1 ; Restore registers
- rts ; Return
-
-
- ResetTimer
- move.l a0,-(sp) ; Save register
- lea counter,a0 ; Get counter address
- clr.l (a0) ; Zero counter
- move.l (sp)+,a0 ; Restore register
- rts ; Return
-
- KillTimer
- movem.l a0-a1,-(sp) ; Save registers
- movea.l VIA,a1 ; Disable VIA interrupts
- move.b #$40,VIER(a1)
- lea LastVIA,a1 ; Restore previous interrupt handler
- movea.l #Lvl1dt,a0 ; in level 1 dispatch table
- move.l (a1),24(a0)
- movem.l (sp)+,a0-a1 ; Restore registers
- rts ; Return
-
- timerValue
- move.l a0,-(sp) ; Save register
- lea counter,a0 ; Get counter address
- move.l (a0),8(sp) ; Return counter value
- move.l (sp)+,a0 ; Restore register
- rts ; Return
-
- ;
- ; This is the VIA Timer1 interrupt handler -- the VIA address is
- ; passed in A1 by the Mac primary interrupt handler.
- ;
- VIArout
- move.b VT1C(a1),d0 ; Clear interrupt flag on VIA
- lea counter,a0 ; Get counter address
- addq.l #1,(a0) ; Increment counter
- rts
-
- Counter dc.l 1 ; Millisecond counter
- LastVIA dc.l 1 ; Save last interrupt handler here.
-
- end
-